package com.ruoyi.ma.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.ma.domain.MaMaterialPlanDetails;
import com.ruoyi.ma.domain.vo.MaMaterialPlanDataDetailsReturnVo;
import com.ruoyi.ma.domain.vo.MaMaterialPlanDetailsVo;
import com.ruoyi.ma.domain.vo.MaMaterialSupplierVo;
import com.ruoyi.ma.mapper.MaMaterialPlanDetailsMapper;
import com.ruoyi.ma.mapper.MaMaterialSupplierMapper;
import com.ruoyi.workflow.service.IWfTaskService;
import com.ruoyi.workflow.service.impl.WfTaskServiceImpl;
import liquibase.pro.packaged.W;
import lombok.RequiredArgsConstructor;
import org.flowable.common.engine.api.query.QueryProperty;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.springframework.stereotype.Service;
import com.ruoyi.ma.domain.bo.MaMaterialPlanBo;
import com.ruoyi.ma.domain.vo.MaMaterialPlanVo;
import com.ruoyi.ma.domain.MaMaterialPlan;
import com.ruoyi.ma.mapper.MaMaterialPlanMapper;
import com.ruoyi.ma.service.IMaMaterialPlanService;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.valueextraction.ExtractedValue;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 材料计划Service业务层处理
 *
 * @author llb
 * @date 2024-11-01
 */
@RequiredArgsConstructor
@Service
public class MaMaterialPlanServiceImpl implements IMaMaterialPlanService {

    private final MaMaterialPlanMapper baseMapper;
    private final MaMaterialSupplierMapper supplierMapper;
    private final MaMaterialPlanDetailsMapper detailsMapper;
    private final TaskService taskService;

    /**
     * 查询材料计划
     */
    @Override
    public MaMaterialPlanVo queryById(Long planId){
        return baseMapper.selectVoById(planId);
    }

    /**
     * 查询材料计划列表
     */
    @Override
    public TableDataInfo<MaMaterialPlanVo> queryPageList(MaMaterialPlanBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<MaMaterialPlan> lqw = buildQueryWrapper(bo);
        lqw.orderByDesc(MaMaterialPlan::getBelongDate);
        Page<MaMaterialPlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        // 查询对应的审批流程信息
        List<MaMaterialPlanVo> records = result.getRecords();

//        records.forEach(item -> {
//            String workflowsStateus = item.getWorkflowsStateus();
//            if (StringUtils.isNotBlank(workflowsStateus) && !"00".equals(workflowsStateus)) {
//                Map<String, Object> map = baseMapper.getActHisVarInfo(item.getPlanId());
//                item.setTaskId(map.get("taskId").toString());
//                item.setProInsId(map.get("proInsId").toString());
//            }
//        });

        // 设置对应的任务信息
        records.forEach(item -> {
            if (ObjectUtils.isNotEmpty(item.getProInsId())) {
                List<Task> taskList = taskService.createTaskQuery().processInstanceId(item.getProInsId()).list();
                if (CollUtil.isNotEmpty(taskList)) {
                    List<Task> sortList = taskList.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())).collect(Collectors.toList());
                    Task task = sortList.get(0);
                    item.setTaskId(task.getId());
                    item.setCurrName(task.getName());
                }
            }
        });

        result.setRecords(records);
        return TableDataInfo.build(result);
    }

    /**
     * 查询材料计划列表
     */
    @Override
    public List<MaMaterialPlanVo> queryList(MaMaterialPlanBo bo) {
        LambdaQueryWrapper<MaMaterialPlan> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<MaMaterialPlan> buildQueryWrapper(MaMaterialPlanBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<MaMaterialPlan> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getBdId() != null, MaMaterialPlan::getBdId, bo.getBdId());
        lqw.eq(bo.getGysId() != null, MaMaterialPlan::getGysId, bo.getGysId());
        lqw.eq(bo.getType() != null, MaMaterialPlan::getType, bo.getType());
        lqw.eq(bo.getBelongDate() != null, MaMaterialPlan::getBelongDate, bo.getBelongDate());
        lqw.eq(bo.getWeaveDate() != null, MaMaterialPlan::getWeaveDate, bo.getWeaveDate());
        lqw.eq(bo.getBeginDate() != null, MaMaterialPlan::getBeginDate, bo.getBeginDate());
        lqw.eq(bo.getEndDate() != null, MaMaterialPlan::getEndDate, bo.getEndDate());
        lqw.eq(StringUtils.isNotBlank(bo.getUnit()), MaMaterialPlan::getUnit, bo.getUnit());
        lqw.eq(StringUtils.isNotBlank(bo.getWorkflowsStateus()), MaMaterialPlan::getWorkflowsStateus, bo.getWorkflowsStateus());
        lqw.eq(StringUtils.isNotBlank(bo.getSendStateus()), MaMaterialPlan::getSendStateus, bo.getSendStateus());
        lqw.eq(StringUtils.isNotBlank(bo.getSignStateus()), MaMaterialPlan::getSignStateus, bo.getSignStateus());
        lqw.eq(StringUtils.isNotBlank(bo.getProInsId()), MaMaterialPlan::getProInsId, bo.getProInsId());
        return lqw;
    }

    /**
     * 新增材料计划
     */
    @Override
    public Boolean insertByBo(MaMaterialPlanBo bo) {
        MaMaterialPlan add = BeanUtil.toBean(bo, MaMaterialPlan.class);
        // 根据供应商id获取站点id和标段id
        MaMaterialSupplierVo sp = supplierMapper.selectVoById(bo.getGysId());
        Long bdId = sp.getBdId();
        Long zdId = sp.getZdId();
        add.setBdId(bdId);
        add.setZdId(zdId);
        // 设置初始状态
        add.setSendStateus("0"); // 未发送
        add.setSignStateus("0"); // 未签收
        add.setWorkflowsStateus("00"); // 未审批
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setPlanId(add.getPlanId());
        }
        return flag;
    }

    /**
     * 修改材料计划
     */
    @Override
    public Boolean updateByBo(MaMaterialPlanBo bo) {
        MaMaterialPlan update = BeanUtil.toBean(bo, MaMaterialPlan.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(MaMaterialPlan entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除材料计划
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 获取明细
     *
     * @param planId
     * @return
     */
    @Override
    public MaMaterialPlanDataDetailsReturnVo getDetails(Long planId) {
        // 查询主表
        MaMaterialPlanVo vo = baseMapper.getById(planId);
        // 查询子表
        // 设置累计采购数量
        List<MaMaterialPlanDetailsVo> detailList = handleTotalPurchaseNumber(planId, vo.getGysId());
        MaMaterialPlanDataDetailsReturnVo data = new MaMaterialPlanDataDetailsReturnVo();
        data.setInfoData(vo);
        data.setDetailList(detailList);
        return data;
    }

    // 处理累计采购数量
    @Transactional
    public List<MaMaterialPlanDetailsVo> handleTotalPurchaseNumber(Long planId, Long gysId) {
        // 获取当前计划详情
        LambdaQueryWrapper<MaMaterialPlanDetails> lqw = Wrappers.lambdaQuery();
        lqw.eq(planId != null, MaMaterialPlanDetails::getPlanId, planId);
        List<MaMaterialPlanDetailsVo> currDetails = detailsMapper.getList(lqw);
        // 获取上一期计划详情
//        List<MaMaterialPlanDetailsVo> preDetails = baseMapper.getPrePlanInfo(planId, gysId);
        List<MaMaterialPlanDetailsVo> preDetails = baseMapper.getLatestMaterialInfo(planId, gysId);
        List<MaMaterialPlanDetails> update = new ArrayList<>();
        if (ObjectUtils.isEmpty(preDetails)) {
            // 没有上一期计划信息,则设置累计采购数量为0
            currDetails.forEach(item -> {
                item.setTotalPurchaseNumber(BigDecimal.ZERO);
                MaMaterialPlanDetails bean = BeanUtil.copyProperties(item, MaMaterialPlanDetails.class);
                update.add(bean);
            });
        } else {
            // 有上一期计划信息
            currDetails.forEach(item -> {
                Optional<MaMaterialPlanDetailsVo> first = preDetails.stream().filter(o -> o.getManifestId().equals(item.getManifestId())).findFirst();
                if (first.isPresent()) {
                    MaMaterialPlanDetailsVo de = first.get();
                    BigDecimal totalPurchaseNumber = de.getTotalPurchaseNumber();
                    BigDecimal monthPurchaseNumber = de.getMonthPurchaseNumber();
                    BigDecimal sum = null;
                    if (ObjectUtils.isNotEmpty(totalPurchaseNumber) && ObjectUtils.isNotEmpty(monthPurchaseNumber)) {
                        sum = totalPurchaseNumber.add(monthPurchaseNumber);
                    } else if (ObjectUtils.isNotEmpty(totalPurchaseNumber) && ObjectUtils.isEmpty(monthPurchaseNumber)) {
                        sum = totalPurchaseNumber;
                    } else if (ObjectUtils.isEmpty(totalPurchaseNumber) && ObjectUtils.isNotEmpty(monthPurchaseNumber)) {
                        sum = monthPurchaseNumber;
                    } else {
                        sum = BigDecimal.ZERO;
                    }
                    item.setTotalPurchaseNumber(sum);
                    MaMaterialPlanDetails bean = BeanUtil.copyProperties(item, MaMaterialPlanDetails.class);
                    update.add(bean);
                }
            });
        }
        if (CollUtil.isNotEmpty(update)) {
            detailsMapper.updateBatchById(update);
        }
        return currDetails;
    }

}
